/* Copyright 2005-2015 Alfresco Software, Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var extScope

angular.module('flowableModeler').controller('DecisionTableDetailsCtrl', [
  '$rootScope',
  '$scope',
  '$translate',
  '$http',
  '$location',
  '$routeParams',
  '$modal',
  '$timeout',
  '$popover',
  'DecisionTableService',
  'hotRegisterer',
  function(
    $rootScope,
    $scope,
    $translate,
    $http,
    $location,
    $routeParams,
    $modal,
    $timeout,
    $popover,
    DecisionTableService,
    hotRegisterer
  ) {
    extScope = $scope

    $scope.decisionTableMode = 'read'

    // Initialize model
    $scope.model = {
      // Store the main model id, this points to the current version of a model,
      // even when we're showing history
      latestModelId: $routeParams.modelId,
      columnDefs: [],
      columnVariableIdMap: {},
      readOnly: true,
      availableVariableTypes: ['string', 'number', 'boolean', 'date', 'collection']
    }

    // Hot Model init
    $scope.model.hotSettings = {
      stretchH: 'all',
      outsideClickDeselects: false,
      manualColumnResize: false,
      readOnly: true,
      disableVisualSelection: true
    }

    var hotReadOnlyDecisionTableEditorInstance
    var hitPolicies = ['FIRST', 'ANY', 'UNIQUE', 'PRIORITY', 'RULE ORDER', 'OUTPUT ORDER', 'COLLECT']
    var operators = [
      '==',
      '!=',
      '<',
      '>',
      '>=',
      '<=',
      'ANY OF',
      'NONE OF',
      'ALL OF',
      'NOT ALL OF',
      'IS IN',
      'IS NOT IN'
    ]
    var columnIdCounter = 0
    var dateFormat = 'YYYY-MM-DD'

    var variableUndefined = $translate.instant('DECISION-TABLE-EDITOR.EMPTY-MESSAGES.NO-VARIABLE-SELECTED')
    // helper for looking up variable id by col id
    $scope.getVariableNameByColumnId = function(colId) {
      if (!colId) {
        return
      }

      if ($scope.model.columnVariableIdMap[colId]) {
        return $scope.model.columnVariableIdMap[colId]
      } else {
        return variableUndefined
      }
    }

    $scope.loadDecisionTable = function() {
      var url, decisionTableUrl
      if ($routeParams.modelHistoryId) {
        url = FLOWABLE.APP_URL.getModelHistoryUrl($routeParams.modelId, $routeParams.modelHistoryId)
        decisionTableUrl = FLOWABLE.APP_URL.getDecisionTableModelsHistoryUrl($routeParams.modelHistoryId)
      } else {
        url = FLOWABLE.APP_URL.getModelUrl($routeParams.modelId)
        decisionTableUrl = FLOWABLE.APP_URL.getDecisionTableModelUrl($routeParams.modelId)
      }

      $http({ method: 'GET', url: url })
        .success(function(data, status, headers, config) {
          //根据人员ID转化人员姓名
          if(data.createdBy){
            $scope.translateUserInfo('create',data.createdBy,data)
          }
          if(data.lastUpdatedBy){
            $scope.translateUserInfo('update',data.lastUpdatedBy,data)
          }
          $scope.model.decisionTable = data
          $scope.model.decisionTableDownloadUrl = decisionTableUrl + '/export?version=' + Date.now()
          $scope.loadVersions()
        })
        .error(function(data, status, headers, config) {
          $scope.returnToList()
        })
    }

    $scope.translateUserInfo = function(type,id,oldData) {
      $http({
        method: 'POST',
        url: FLOWABLE.APP_URL.getUserInfoUrl(),
        data: {id: id}
      }).success(function(data, status, headers, config) {
        if(data && type == 'create'){
          oldData.createdBy = data.userName
        }else if(data && type == 'update'){
          oldData.lastUpdatedBy = data.userName
        }
        $scope.model.decisionTable = oldData
      })
    }

    $scope.downloadDecisionTable = function() {
      jQuery.ajax({
        type: 'HEAD',
        url: $scope.model.decisionTableDownloadUrl,
        complete: function(xhr, data) {
          var fileName = xhr.getResponseHeader('content-disposition').split("''")[1]
          $http({ method: 'GET', url: $scope.model.decisionTableDownloadUrl, responseType: 'blob' }).success(function(
            data,
            status,
            headers,
            config
          ) {
            const hrefValue = window.URL.createObjectURL(data)
            const a = document.createElement('a')
            a.setAttribute('href', hrefValue)
            a.download = decodeURIComponent(fileName)
            document.body.append(a)
            a.click()
            a.remove()
          })
        }
      })
    }

    $scope.useAsNewVersion = function() {
      _internalCreateModal(
        {
          template: 'views/popup/model-use-as-new-version.html',
          scope: $scope
        },
        $modal,
        $scope
      )
    }

    $scope.toggleFavorite = function() {
      $scope.model.favoritePending = true

      var data = {
        favorite: !$scope.model.decisionTable.favorite
      }

      $http({ method: 'PUT', url: FLOWABLE.APP_URL.getModelUrl($scope.model.latestModelId), data: data })
        .success(function(data, status, headers, config) {
          $scope.model.favoritePending = false
          if ($scope.model.decisionTable.favorite) {
            $scope.addAlertPromise($translate('DECISION-TABLE.ALERT.UN-FAVORITE-CONFIRM'), 'info')
          } else {
            $scope.addAlertPromise($translate('DECISION-TABLE.ALERT.FAVORITE-CONFIRM'), 'info')
          }
          $scope.model.decisionTable.favorite = !$scope.model.decisionTable.favorite
        })
        .error(function(data, status, headers, config) {
          $scope.model.favoritePending = false
        })
    }

    $scope.loadVersions = function() {
      var params = {
        includeLatestVersion: !$scope.model.decisionTable.latestVersion
      }

      $http({
        method: 'GET',
        url: FLOWABLE.APP_URL.getModelHistoriesUrl($scope.model.latestModelId),
        params: params
      }).success(function(data, status, headers, config) {
        if ($scope.model.decisionTable.latestVersion) {
          if (!data.data) {
            data.data = []
          }
          data.data.unshift($scope.model.decisionTable)
        }

        $scope.model.versions = data
      })
    }

    $scope.showVersion = function(version) {
      if (version) {
        if (version.latestVersion) {
          $location.path('/decision-tables/' + $scope.model.latestModelId)
        } else {
          // Show latest version, no history-suffix needed in URL
          $location.path('/decision-tables/' + $scope.model.latestModelId + '/history/' + version.id)
        }
      }
    }

    $scope.returnToList = function() {
      $location.path('/decision-tables/')
    }

    $scope.editDecisionTable = function() {
      _internalCreateModal(
        {
          template: 'views/popup/model-edit.html',
          scope: $scope
        },
        $modal,
        $scope
      )
    }

    $scope.duplicateDecisionTable = function() {
      var modalInstance = _internalCreateModal(
        {
          template: 'views/popup/decision-table-duplicate.html?version=' + Date.now()
        },
        $modal,
        $scope
      )

      modalInstance.$scope.originalModel = $scope.model

      modalInstance.$scope.duplicateDecisionTableCallback = function(result) {
        $rootScope.editorHistory = []
        $location.url('/decision-table-editor/' + encodeURIComponent(result.id))
      }
    }

    $scope.deleteDecisionTable = function() {
      _internalCreateModal(
        {
          template: 'views/popup/model-delete.html',
          scope: $scope
        },
        $modal,
        $scope
      )
    }

    $scope.shareDecisionTable = function() {
      _internalCreateModal(
        {
          template: 'views/popup/model-share.html',
          scope: $scope
        },
        $modal,
        $scope
      )
    }

    $scope.openEditor = function() {
      if ($scope.model.decisionTable) {
        $location.path('/decision-table-editor/' + $scope.model.decisionTable.id)
      }
    }

    $scope.toggleHistory = function($event) {
      if (!$scope.historyState) {
        var state = {}
        $scope.historyState = state

        // Create popover
        state.popover = $popover(angular.element($event.target), {
          template: 'views/popover/history.html',
          placement: 'bottom-right',
          show: true,
          scope: $scope,
          container: 'body'
        })

        var destroy = function() {
          state.popover.destroy()
          delete $scope.historyState
        }

        // When popup is hidden or scope is destroyed, hide popup
        state.popover.$scope.$on('tooltip.hide', destroy)
        $scope.$on('$destroy', destroy)
      }
    }

    $scope.doAfterGetColHeader = function(col, TH) {
      if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].expressionType === 'input-operator') {
        TH.className += 'input-operator-header'
      } else if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].expressionType === 'input-expression') {
        TH.className += 'input-expression-header'
        if ($scope.model.startOutputExpression - 1 === col) {
          TH.className += ' last'
        }
      } else if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].expressionType === 'output') {
        TH.className += 'output-header'
        if ($scope.model.startOutputExpression === col) {
          TH.className += ' first'
        }
      }
    }

    $scope.doAfterModifyColWidth = function(width, col) {
      if ($scope.model.columnDefs[col] && $scope.model.columnDefs[col].width) {
        var settingsWidth = $scope.model.columnDefs[col].width
        if (settingsWidth > width) {
          return settingsWidth
        }
      }
      return width
    }

    $scope.doAfterRender = function() {
      var element = document.querySelector('thead > tr > th:first-of-type')
      if (element) {
        var firstChild = element.firstChild
        var newElement = angular.element(
          '<div class="hit-policy-header"><a onclick="triggerHitPolicyEditor()">' +
            $scope.currentDecisionTable.hitIndicator.substring(0, 1) +
            '</a></div>'
        )
        element.className = 'hit-policy-container'
        element.replaceChild(newElement[0], firstChild)
      }

      $timeout(function() {
        hotReadOnlyDecisionTableEditorInstance = hotRegisterer.getInstance('read-only-decision-table-editor')
        if (hotReadOnlyDecisionTableEditorInstance) {
          hotReadOnlyDecisionTableEditorInstance.validateCells()
        }
      })
    }

    $scope.doAfterValidate = function(isValid, value, row, prop, source) {
      if (isCorrespondingCollectionOperator(row, prop)) {
        return true
      } else if (isCustomExpression(value) || isDashValue(value)) {
        disableCorrespondingOperatorCell(row, prop)
        return true
      } else {
        enableCorrespondingOperatorCell(row, prop)
      }
    }

    var isCustomExpression = function(val) {
      return !!(val != null && (String(val).startsWith('${') || String(val).startsWith('#{')))
    }

    var isDashValue = function(val) {
      return !!(val != null && '-' === val)
    }

    var isCorrespondingCollectionOperator = function(row, prop) {
      var operatorCol = getCorrespondingOperatorCell(row, prop)
      var operatorCellMeta = hotReadOnlyDecisionTableEditorInstance.getCellMeta(row, operatorCol)

      var isCollectionOperator = false
      if (isOperatorCell(operatorCellMeta)) {
        var operatorValue = hotReadOnlyDecisionTableEditorInstance.getDataAtCell(row, operatorCol)
        if (
          operatorValue === 'IN' ||
          operatorValue === 'NOT IN' ||
          operatorValue === 'ANY' ||
          operatorValue === 'NOT ANY'
        ) {
          isCollectionOperator = true
        }
      }
      return isCollectionOperator
    }

    var disableCorrespondingOperatorCell = function(row, prop) {
      var operatorCol = getCorrespondingOperatorCell(row, prop)
      var operatorCellMeta = hotReadOnlyDecisionTableEditorInstance.getCellMeta(row, operatorCol)

      if (!isOperatorCell(operatorCellMeta)) {
        return
      }

      if (
        operatorCellMeta.className != null &&
        operatorCellMeta.className.indexOf('custom-expression-operator') !== -1
      ) {
        return
      }

      var currentEditor = hotReadOnlyDecisionTableEditorInstance.getCellEditor(row, operatorCol)

      hotReadOnlyDecisionTableEditorInstance.setCellMeta(
        row,
        operatorCol,
        'className',
        operatorCellMeta.className + ' custom-expression-operator'
      )
      hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'originalEditor', currentEditor)
      hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'editor', false)
      hotReadOnlyDecisionTableEditorInstance.setDataAtCell(row, operatorCol, null)
    }

    var enableCorrespondingOperatorCell = function(row, prop) {
      var operatorCol = getCorrespondingOperatorCell(row, prop)
      var operatorCellMeta = hotReadOnlyDecisionTableEditorInstance.getCellMeta(row, operatorCol)

      if (!isOperatorCell(operatorCellMeta)) {
        return
      }

      if (
        operatorCellMeta == null ||
        operatorCellMeta.className == null ||
        operatorCellMeta.className.indexOf('custom-expression-operator') == -1
      ) {
        return
      }

      operatorCellMeta.className = operatorCellMeta.className.replace('custom-expression-operator', '')
      hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'className', operatorCellMeta.className)
      hotReadOnlyDecisionTableEditorInstance.setCellMeta(row, operatorCol, 'editor', operatorCellMeta.originalEditor)
      hotReadOnlyDecisionTableEditorInstance.setDataAtCell(row, operatorCol, '==')
    }

    var getCorrespondingOperatorCell = function(row, prop) {
      var currentCol = hotReadOnlyDecisionTableEditorInstance.propToCol(prop)
      if (currentCol < 1) {
        return
      }
      var operatorCol = currentCol - 1
      return operatorCol
    }

    var isOperatorCell = function(cellMeta) {
      return !(
        cellMeta == null ||
        cellMeta.prop == null ||
        typeof cellMeta.prop !== 'string' ||
        cellMeta.prop.endsWith('_operator') === false
      )
    }

    var createNewInputExpression = function(inputExpression) {
      var newInputExpression
      if (inputExpression) {
        newInputExpression = {
          id: _generateColumnId(),
          label: inputExpression.label,
          variableId: inputExpression.variableId,
          type: inputExpression.type,
          newVariable: inputExpression.newVariable,
          entries: inputExpression.entries
        }
      } else {
        newInputExpression = {
          id: _generateColumnId(),
          label: null,
          variableId: null,
          type: null,
          newVariable: null,
          entries: null
        }
      }
      return newInputExpression
    }

    $scope.openHitPolicyEditor = function() {
      var editTemplate = 'views/popup/decision-table-edit-hit-policy.html'

      $scope.model.hitPolicy = $scope.currentDecisionTable.hitIndicator

      _internalCreateModal(
        {
          template: editTemplate,
          scope: $scope
        },
        $modal,
        $scope
      )
    }

    $scope.openInputExpressionEditor = function(expressionPos, newExpression) {
      var editTemplate = 'views/popup/decision-table-edit-input-expression.html'

      $scope.model.newExpression = !!newExpression

      if (!$scope.model.newExpression) {
        $scope.model.selectedExpression = $scope.currentDecisionTable.inputExpressions[expressionPos]
      } else {
        if (expressionPos >= $scope.model.startOutputExpression) {
          $scope.model.selectedColumn = $scope.model.startOutputExpression - 1
        } else {
          $scope.model.selectedColumn = Math.floor(expressionPos / 2)
        }
      }

      _internalCreateModal(
        {
          template: editTemplate,
          scope: $scope
        },
        $modal,
        $scope
      )
    }

    $scope.openOutputExpressionEditor = function(expressionPos, newExpression) {
      var editTemplate = 'views/popup/decision-table-edit-output-expression.html'

      $scope.model.newExpression = !!newExpression
      $scope.model.hitPolicy = $scope.currentDecisionTable.hitIndicator
      $scope.model.selectedColumn = expressionPos

      if (!$scope.model.newExpression) {
        $scope.model.selectedExpression = $scope.currentDecisionTable.outputExpressions[expressionPos]
      }

      _internalCreateModal(
        {
          template: editTemplate,
          scope: $scope
        },
        $modal,
        $scope
      )
    }

    var createNewOutputExpression = function(outputExpression) {
      var newOutputExpression
      if (outputExpression) {
        newOutputExpression = {
          id: _generateColumnId(),
          label: outputExpression.label,
          variableId: outputExpression.variableId,
          type: outputExpression.variableType,
          newVariable: outputExpression.newVariable,
          entries: outputExpression.entries
        }
      } else {
        newOutputExpression = {
          id: _generateColumnId(),
          label: null,
          variableId: null,
          type: null,
          newVariable: null,
          entries: null
        }
      }
      return newOutputExpression
    }

    var _loadDecisionTableDefinition = function(modelId, historyId) {
      DecisionTableService.fetchDecisionTableDetails(modelId, historyId).then(function(decisionTable) {
        $rootScope.currentDecisionTable = decisionTable.decisionTableDefinition
        $rootScope.currentDecisionTable.id = decisionTable.id
        $rootScope.currentDecisionTable.key = decisionTable.decisionTableDefinition.key
        $rootScope.currentDecisionTable.name = decisionTable.name
        $rootScope.currentDecisionTable.description = decisionTable.description

        // decision table model to used in save dialog
        $rootScope.currentDecisionTableModel = {
          id: decisionTable.id,
          name: decisionTable.name,
          key: decisionTable.decisionTableDefinition.key,
          description: decisionTable.description
        }

        if (!$rootScope.currentDecisionTable.hitIndicator) {
          $rootScope.currentDecisionTable.hitIndicator = hitPolicies[0]
        }

        evaluateDecisionTableGrid($rootScope.currentDecisionTable)
      })
    }

    var evaluateDecisionTableGrid = function(decisionTable) {
      $scope.evaluateDecisionHeaders(decisionTable)
      evaluateDecisionGrid(decisionTable)
    }

    var setGridValues = function(key, type) {
      if ($scope.model.rulesData) {
        $scope.model.rulesData.forEach(function(rowData) {
          if (type === 'input-operator') {
            if (!(key in rowData) || rowData[key] === '') {
              rowData[key] = '=='
            }
          }
          // else if (type === 'input-expression') {
          //     if (!(key in rowData) || rowData[key] === '') {
          //         rowData[key] = '-';
          //     }
          // }
        })
      }
    }

    var evaluateDecisionGrid = function(decisionTable) {
      var tmpRuleGrid = []

      // rows
      if (decisionTable.rules && decisionTable.rules.length > 0) {
        decisionTable.rules.forEach(function(rule) {
          // rule data
          var tmpRowValues = {}
          for (var i = 0; i < Object.keys(rule).length; i++) {
            var id = Object.keys(rule)[i]

            $scope.model.columnDefs.forEach(function(columnDef) {
              // set counter to max value
              var expressionId = 0
              try {
                expressionId = parseInt(columnDef.expression.id)
              } catch (e) {}
              if (expressionId > columnIdCounter) {
                columnIdCounter = expressionId
              }
            })

            tmpRowValues[id] = rule[id]
          }

          tmpRuleGrid.push(tmpRowValues)
        })
      } else {
        // initialize default values
        tmpRuleGrid.push(createDefaultRow())
      }
      // $rootScope.currentDecisionTableRules = tmpRuleGrid;
      $scope.model.rulesData = tmpRuleGrid
    }

    var createDefaultRow = function() {
      var defaultRow = {}
      $scope.model.columnDefs.forEach(function(columnDefinition) {
        if (columnDefinition.expressionType === 'input-operator') {
          defaultRow[columnDefinition.data] = '=='
        }
        // else if (columnDefinition.expressionType === 'input-expression') {
        //     defaultRow[columnDefinition.data] = '-';
        // }
        else if (columnDefinition.expressionType === 'output') {
          defaultRow[columnDefinition.data] = ''
        }
      })

      return defaultRow
    }

    var composeInputOperatorColumnDefinition = function(inputExpression) {
      var expressionPosition = $scope.currentDecisionTable.inputExpressions.indexOf(inputExpression)

      var columnDefinition = {
        data: inputExpression.id + '_operator',
        expressionType: 'input-operator',
        expression: inputExpression,
        width: '70',
        className: 'input-operator-cell',
        type: 'dropdown',
        source: operators
      }

      return columnDefinition
    }

    var composeInputExpressionColumnDefinition = function(inputExpression) {
      var expressionPosition = $scope.currentDecisionTable.inputExpressions.indexOf(inputExpression)

      var type
      switch (inputExpression.type) {
        case 'date':
          type = 'date'
          break
        case 'number':
          type = 'numeric'
          break
        case 'boolean':
          type = 'dropdown'
          break
        default:
          type = 'text'
      }

      var columnDefinition = {
        data: inputExpression.id + '_expression',
        type: type,
        title:
          '<div class="input-header">' +
          "<a onclick=\"triggerExpressionEditor('input'," +
          expressionPosition +
          ',false)"><span class="header-label">' +
          (inputExpression.label ? inputExpression.label : 'New Input') +
          '</span></a>' +
          '<br><span class="header-variable">' +
          (inputExpression.variableId ? inputExpression.variableId : 'none') +
          '</span>' +
          '<br/><span class="header-variable-type">' +
          (inputExpression.type ? inputExpression.type : '') +
          '</brspan>' +
          '</div>',
        expressionType: 'input-expression',
        expression: inputExpression,
        className: 'htCenter',
        width: '200'
      }

      if (inputExpression.entries && inputExpression.entries.length > 0) {
        var entriesOptionValues = inputExpression.entries.slice(0, inputExpression.entries.length)
        entriesOptionValues.push('-', '', ' ')

        columnDefinition.type = 'dropdown'
        columnDefinition.strict = true
        columnDefinition.source = entriesOptionValues

        columnDefinition.title =
          '<div class="input-header">' +
          "<a onclick=\"triggerExpressionEditor('input'," +
          expressionPosition +
          ',false)"><span class="header-label">' +
          (inputExpression.label ? inputExpression.label : 'New Input') +
          '</span></a>' +
          '<br><span class="header-variable">' +
          (inputExpression.variableId ? inputExpression.variableId : 'none') +
          '</span>' +
          '<br/><span class="header-variable-type">' +
          (inputExpression.type ? inputExpression.type : '') +
          '</span>' +
          '<br><span class="header-entries">[' +
          inputExpression.entries.join() +
          ']</span>' +
          '</div>'
      }

      if (type === 'date') {
        columnDefinition.dateFormat = dateFormat
      } else if (type === 'dropdown') {
        columnDefinition.source = ['true', 'false', '-']
      }

      return columnDefinition
    }

    var composeOutputColumnDefinition = function(outputExpression) {
      var expressionPosition = $scope.currentDecisionTable.outputExpressions.indexOf(outputExpression)

      var type
      switch (outputExpression.type) {
        case 'date':
          type = 'date'
          break
        case 'number':
          type = 'numeric'
          break
        case 'boolean':
          type = 'dropdown'
          break
        default:
          type = 'text'
      }

      var title = ''
      var columnDefinition = {
        data: outputExpression.id,
        type: type,
        expressionType: 'output',
        expression: outputExpression,
        className: 'htCenter',
        width: '270'
      }

      if (outputExpression.entries && outputExpression.entries.length > 0) {
        var entriesOptionValues = outputExpression.entries.slice(0, outputExpression.entries.length)
        columnDefinition.type = 'dropdown'
        columnDefinition.source = entriesOptionValues
        columnDefinition.strict = true

        title +=
          '<div class="output-header">' +
          "<a onclick=\"triggerExpressionEditor('output'," +
          expressionPosition +
          ',false)"><span class="header-label">' +
          (outputExpression.label ? outputExpression.label : 'New Output') +
          '</span></a>' +
          '<br><span class="header-variable">' +
          (outputExpression.variableId ? outputExpression.variableId : 'none') +
          '</span>' +
          '<br/><span class="header-variable-type">' +
          (outputExpression.type ? outputExpression.type : '') +
          '</span>' +
          '<br><span class="header-entries">[' +
          outputExpression.entries.join() +
          ']</span>' +
          '</div>'
      } else {
        title +=
          '<div class="output-header">' +
          "<a onclick=\"triggerExpressionEditor('output'," +
          expressionPosition +
          ',false)"><span class="header-label">' +
          (outputExpression.label ? outputExpression.label : 'New Output') +
          '</span></a>' +
          '<br><span class="header-variable">' +
          (outputExpression.variableId ? outputExpression.variableId : 'none') +
          '</span>' +
          '<br/><span class="header-variable-type">' +
          (outputExpression.type ? outputExpression.type : '') +
          '</span>' +
          '</div>'
      }

      if (type === 'date') {
        columnDefinition.dateFormat = dateFormat
      } else if (type === 'dropdown') {
        columnDefinition.source = ['true', 'false', '-']
      }

      columnDefinition.title = title

      return columnDefinition
    }

    $scope.evaluateDecisionHeaders = function(decisionTable) {
      var columnDefinitions = []
      var inputExpressionCounter = 0
      if (decisionTable.inputExpressions && decisionTable.inputExpressions.length > 0) {
        decisionTable.inputExpressions.forEach(function(inputExpression) {
          var inputOperatorColumnDefinition = composeInputOperatorColumnDefinition(inputExpression)
          columnDefinitions.push(inputOperatorColumnDefinition)
          setGridValues(inputOperatorColumnDefinition.data, inputOperatorColumnDefinition.expressionType)

          var inputExpressionColumnDefinition = composeInputExpressionColumnDefinition(inputExpression)
          columnDefinitions.push(inputExpressionColumnDefinition)
          setGridValues(inputExpressionColumnDefinition.data, inputExpressionColumnDefinition.expressionType)

          inputExpressionCounter += 2
        })
      } else {
        // create default input expression
        decisionTable.inputExpressions = []
        var inputExpression = createNewInputExpression()
        decisionTable.inputExpressions.push(inputExpression)
        columnDefinitions.push(composeInputOperatorColumnDefinition(inputExpression))
        columnDefinitions.push(composeInputExpressionColumnDefinition(inputExpression))
        inputExpressionCounter += 2
      }

      columnDefinitions[inputExpressionCounter - 1].className += ' last'
      $scope.model.startOutputExpression = inputExpressionCounter

      if (decisionTable.outputExpressions && decisionTable.outputExpressions.length > 0) {
        decisionTable.outputExpressions.forEach(function(outputExpression) {
          columnDefinitions.push(composeOutputColumnDefinition(outputExpression))
        })
      } else {
        // create default output expression
        decisionTable.outputExpressions = []
        var outputExpression = createNewOutputExpression()
        decisionTable.outputExpressions.push(outputExpression)
        columnDefinitions.push(composeOutputColumnDefinition(outputExpression))
      }

      columnDefinitions[inputExpressionCounter].className += ' first'

      // timeout needed for trigger hot update when removing column defs
      $scope.model.columnDefs = columnDefinitions
      $timeout(function() {
        if (hotReadOnlyDecisionTableEditorInstance) {
          hotReadOnlyDecisionTableEditorInstance.render()
        }
      })
    }

    // fetch table from service and populate model
    _loadDecisionTableDefinition($routeParams.modelId, $routeParams.modelHistoryId)

    var _generateColumnId = function() {
      columnIdCounter++
      return '' + columnIdCounter
    }

    // Load model needed for favorites
    $scope.loadDecisionTable()
  }
])
